package com.onlyoffice.demo.onlyoffice.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.onlyoffice.demo.onlyoffice.domain.File;
import com.onlyoffice.demo.onlyoffice.service.IFileService;
import com.onlyoffice.model.documenteditor.Callback;
import com.onlyoffice.model.documenteditor.callback.Action;
import com.onlyoffice.service.documenteditor.callback.CallbackService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

/**
 * 回调服务实现类
 *
 * @author ZWX
 * @date 2025-07-08
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class FileCallbackServiceImpl implements CallbackService {
    @Value("${onlyoffice.security.enable}")
    private Boolean securityEnable;
    @Value("${onlyoffice.security.key}")
    private String securityKey;
    @Value("${onlyoffice.uploadPath}")
    private String uploadPath;

    private final ObjectMapper objectMapper = new ObjectMapper();
    private final IFileService fileService;

    /**
     * 回调参数校验
     *
     * @param callback 回调参数
     * @param authorizationHeader 授权报头
     * @return 回调参数
     */
    @Override
    public Callback verifyCallback(Callback callback, String authorizationHeader) throws JsonProcessingException {
        // 判断是否开启jwt校验
        if (Boolean.FALSE.equals(securityEnable)) {
            return callback;
        }
        String token = callback.getToken();
        boolean fromHeader = false;
        if (StrUtil.isBlank(token) && StrUtil.isNotBlank(authorizationHeader)) {
            token = authorizationHeader.replace("Bearer ", "");
            fromHeader = true;
        }
        if (StrUtil.isBlank(token)) {
            throw new RuntimeException("token不存在");
        }
        // TODO 实现JwtManager
//        DefaultJwtManager jwtManager = new DefaultJwtManager();
//        String payload = jwtManager.verifyToken(token, securityKey);
//        if (fromHeader) {
//            JsonNode jsonNode = objectMapper.readTree(payload);
//            JsonNode callbackFromToken = jsonNode.get("payload");
//            return objectMapper.readValue(callbackFromToken.toString(), Callback.class);
//        } else {
//            return objectMapper.readValue(payload, Callback.class);
//        }
        return callback;
    }

    @Override
    public void processCallback(Callback callback, String fileId) throws Exception {
        switch (callback.getStatus()) {
            case EDITING:
                handlerEditing(callback, fileId);
                break;
            case SAVE:
                handlerSave(callback, fileId);
                break;
            case SAVE_CORRUPTED:
                handlerSaveCorrupted(callback, fileId);
                break;
            case CLOSED:
                handlerClosed(callback, fileId);
                break;
            case FORCESAVE:
                handlerForcesave(callback, fileId);
                break;
            case FORCESAVE_CORRUPTED:
                handlerForcesaveCurrupted(callback, fileId);
                break;
            default:
                throw new RuntimeException("Callback has no status");
        }
    }

    @Override
    public void handlerEditing(Callback callback, String fileId) throws Exception {
        Action action = callback.getActions().get(0);
        String userid = action.getUserid();
    }

    @Override
    public void handlerSave(Callback callback, String fileId) throws Exception {
        // changesurl
        // http://192.168.10.204:90/cache/files/data/38aa52825c55489ea20fb11ec891e94c_6532/changes.zip/changes.zip?md5=jQ2aOSk4sVSelANQZml2sw&expires=1752198802&shardkey=38aa52825c55489ea20fb11ec891e94c&filename=changes.zip
        //
        String downloadUrl = callback.getUrl();
        if (StrUtil.isBlank(downloadUrl)) {
            return;
        }
        File file = fileService.getById(Long.valueOf(fileId));
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.add("Accept", "application/octet-stream");
        ResponseEntity<byte[]> response = restTemplate.exchange(
            downloadUrl,
            HttpMethod.GET,
            new HttpEntity<>(headers),
            byte[].class
        );
        InputStream is = new ByteArrayInputStream(response.getBody());
        FileUtil.writeFromStream(is, uploadPath + "/" + file.getFileName());
        is.close();

        // 更新文件key
        file.setFileKey(IdUtil.simpleUUID());
        fileService.updateById(file);
    }

    @Override
    public void handlerSaveCorrupted(Callback callback, String fileId) throws Exception {
        handlerSave(callback, fileId);
    }

    @Override
    public void handlerClosed(Callback callback, String fileId) throws Exception {
        // closed 不需要处理
    }

    @Override
    public void handlerForcesave(Callback callback, String fileId) throws Exception {
        handlerSave(callback, fileId);
    }

    @Override
    public void handlerForcesaveCurrupted(Callback callback, String fileId) throws Exception {
        handlerSave(callback, fileId);
    }
}
